<?php

namespace App\Http\Controllers\Admin\Customer;

use App\Exceptions\AppException;
use App\Exports\SmallBagExport;
use App\Http\Controllers\Admin\CallBack;
use App\Http\Controllers\Controller;
use App\Models\lazada\ApiModel;
use App\Models\lazada\ExceptionModel;
use App\Models\lazada\LogModel;
use App\Models\lazada\NodeModel;
use App\Models\lazada\NodeRecordModel;
use App\Models\customer\RepairModel;
use App\Models\FlightModel;
use App\Models\OrderModel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;
use App\Models\lazada\OrderModel as LazadaOrderModel;
use App\Models\lazada\BigBagModel;

class SmallBag extends Controller
{

    /**
     * Notes:列表
     * User: xiangzi
     * Date: 2024/9/5
     * Time: 14:35
     * @return \Illuminate\Http\JsonResponse
     */
    public function list(Request $request) {
        $page = $request->input('page', 1);
        $limit = $request->input('limit', 20);
        $orderCode = $request->input('order_code', '');
        $trackingNumber = $request->input('trackingNumber', '');
        $bigBagID = $request->input('bigBagID', '');
        $take_order_sn = $request->input('take_order_sn', '');
        $des_country_id = $request->input('des_country_id', '');
        $customer_id = $request->input('customer_id', '');
        $node_id = $request->input('node_id', '');
//        $warehouse_id = $request->input('warehouse_id', '');
        $start_time = $request->input('startTime', '');
        $end_time = $request->input('endTime', '');
        $goods_attr = $request->input('goods_attr', '');
        $is_update = $request->input('is_update', '');

        $query = LazadaOrderModel::query()->with(['take_order', 'bigbag', 'destination', 'system_node', 'platform_node', 'bigbag']);

        if($orderCode){
            $query->where('orderCode', $orderCode);
        }

        if ($trackingNumber) {
            $query->where('trackingNumber', $trackingNumber);
        }

        if($node_id){
            $query->where('system_node_id', $node_id);
        }

        if($goods_attr){
            $query->where('goods_attr', $goods_attr);
        }

        if($bigBagID){
            $query->where('bigBagID', $bigBagID);
        }

        if ($des_country_id) {
            $query->where('des_country_id', $des_country_id);
        }

        if ($customer_id) {
            $query->where('customer_id', $customer_id);
        }

        if($is_update != ''){
            if($is_update == 1){
                $query->whereColumn('system_node_id', '=', 'platform_node_id');
            }else{
                $query->whereColumn('system_node_id', '<>', 'platform_node_id');
            }
        }

        if($start_time && $end_time){
            $query->whereBetween('created_at', [$start_time, $end_time]);
        }

        $total = $query->count('id');
        $total_big = LazadaOrderModel::query()->groupBy('bigBagID')->count();
        $total_take_order = LazadaOrderModel::query()->where('take_order_id', '>', 0)->groupBy('take_order_id')->count();
        $total_weight = LazadaOrderModel::query()->sum('weight');
        $items = $query
            ->offset(($page-1) * $limit)
            ->limit($limit)
            ->orderBy('id', 'desc')
            ->get();

        $list = $items->map(function($item) {

            $res = [
                'id' => $item->id,
                'customer_name' => $item->customer->name ?? '',
                'des_country_code' => $item->des_country_code ?? '',
                'orderCode' => $item->orderCode,
                'trackingNumber' => $item->trackingNumber,
                'bigBagID' => $item->bigBagID,
                'take_order_sn' => $item->take_order->sn ?? '',
                'weight' => round($item->weight / 1000, 2),
                'goods_attr' => OrderModel::GOODS_ATTR_MAPS[$item->goods_attr] ?? '',
                'created_at' => $item->created_at->toDateTimeString(),
                'system_node' => $item->system_node->name_cn ?? '',
                'platform_node' => $item->platform_node->name_cn ?? '',
            ];
            return $res;
        });



        $statistic = [
            'total_order' => $total,
            'total_take_order' => $total_take_order,
            'total_big' => $total_big,
            'total_weight' => round($total_weight / 1000, 2),
        ];

        return $this->success(['list' => $list, 'total' => $total, 'statistic' => $statistic]);
    }

    //详情
    public function detail(Request $request) {
        $id = $request->input('id');

        $order = LazadaOrderModel::with(['take_order', 'bigbag', 'destination'])->find($id);

        if (!$order) {
            return  $this->error('数据不存在');
        }

        $sender = json_decode($order->sender, true);
        $receiver = json_decode($order->receiver, true);

        $return = [
            'customer_name' => $order->customer->name ?? '',
            'orderCode' => $order->orderCode,
            'trackingNumber' => $order->trackingNumber,
            'bigBagID' => $order->bigBagID,
            'take_order_sn' => $order->take_order->sn ?? '',
            'des_country_name' => $order->des_country_code ?? '',
            'weight' => round($order->weight / 1000, 2),
            'goods_attr' => OrderModel::GOODS_ATTR_MAPS[$order->goods_attr] ?? '',
            'price' => $order->price . $order->priceUnit,
            'sender' => [
                'name' => $sender['name'] ?? '',
                'phone' => $sender['phone'] ?? '',
                'mobile' => $sender['mobile'] ?? '',
                'address' => $sender['address'] ?? [],
            ],
            'receiver' => [
                'name' => $receiver['name'] ?? '',
                'phone' => $receiver['phone'] ?? '',
                'mobile' => $receiver['mobile'] ?? '',
                'address' => $receiver['address'] ?? [],
            ]
        ];

        $flight_info = []; $cost_info = [];
        if($order->take_order_id){
            $flight = $order->take_order->flight;
            if($flight){
                $flight_lines = $flight->items;
                $routes = []; $flight_numbers = []; $start_port = []; $arrive_port = []; $destination = [];
                foreach ($flight_lines as $line){
                    $routes[] = $line->route->name ?? '';
                    $flight_numbers[] = $line->air_line->flight_number ?? '';
                    $start_port[] = $line->start_port->name ?? '';
                    $arrive_port[] = $line->arrive_port->name ?? '';
                    $destination[] = $line->destination->name ?? '';
                }
                $transfer_port = $arrive_port;
                array_pop($transfer_port);
                $flight_info = [
                    'route' => implode(',', $routes),
                    'flight_number' => implode(',', $flight_numbers),
                    'take_off_time' => $flight->take_off_time,
                    'destination_name' => implode(',', $destination),
                    'start_port' => implode(',', $start_port),
                    'transfer_port' => implode(',', $transfer_port),
                    'arrive_port' => implode(',', $arrive_port),
                    'unload_warehouse' => $item->unload_warehouse->name ?? '',
                    'status_text' => FlightModel::STATUS_MAPS[$flight->status] ?? '',
                ];
            }

            $order_symbols = $order->currency->symbol ?? '';
            $cost_info = [
                ['name' => '调拨费', 'amount' => $order_symbols.$order->transfer_amount, 'type' => '系统生成', 'operator' => '-', 'created_at' => $order->created_at->toDateTimeString()],
                ['name' => '报关费', 'amount' => $order_symbols.$order->declare_amount, 'type' => '系统生成', 'operator' => '-', 'created_at' => $order->created_at->toDateTimeString()],
                ['name' => '空运费', 'amount' => $order_symbols.$order->airport_amount, 'type' => '系统生成', 'operator' => '-', 'created_at' => $order->created_at->toDateTimeString()],
                ['name' => '清关费', 'amount' => $order_symbols.$order->clearance_amount, 'type' => '系统生成', 'operator' => '-', 'created_at' => $order->created_at->toDateTimeString()],
                ['name' => '派送费', 'amount' => $order_symbols.$order->dispatch_amount, 'type' => '系统生成', 'operator' => '-', 'created_at' => $order->created_at->toDateTimeString()],
            ];
            $cost_total = [$order->currency_id => [
                'amount' => $order->total_amount,
                'symbol' => $order->currency->symbol ?? '',
            ]];

            $repair = RepairModel::where('asn_id', $id)->get();
            foreach ($repair as $item){
                $repair_symbol = $item->currency->symbol ?? '';
                $cost_info[] = [
                    'name' => $item->subject->name ?? '',
                    'amount' => $repair_symbol.$item->amount,
                    'type' => '人工补录',
                    'operator' => $item->created_admin->staff->name ?? '',
                    'created_at' => $item->created_at->toDateTimeString(),
                ];

                if(isset($cost_total[$item->currency_id])){
                    $cost_total[$item->currency_id]['amount'] += $item->amount;
                }else{
                    $cost_total[$item->currency_id] = [
                        'amount' => $item->amount,
                        'symbol' => $item->currency->symbol ?? '',
                    ];
                }
            }

            $cost_total_str = '';
            foreach ($cost_total as $key => $item){
                $cost_total_str .= $item['symbol'].$item['amount'].',';
            }

            $cost_info[] = [
                'name' => '总计',
                'amount' => $cost_total_str,
                'type' => '',
                'operator' => '',
                'created_at' => ''
            ];

        }

        $logistics_info = [];

        $notify = BigBagModel::where('bigBagID', $order->bigBagID)->first();
        if($notify){
            $record = NodeRecordModel::where('bigbag_id', $notify->id)->orderBy('id', 'desc')->get();

            $list = $record->map(function ($item) {
                return [
                    'id' => $item->id,
                    'node_name' => $item->node->name_cn,
                    'callback_status' => $item->type == 1 ? '-' : '已回传',
                    'datetime' => $item->datetime,
                    'created_at' => $item->created_at->toDateTimeString()
                ];
            });
            $logistics_info = $list->toArray();
        }

        $return['flight_info'] = $flight_info;
        $return['cost_info'] = $cost_info;
        $return['logistics_info'] = $logistics_info;

        return $this->success($return);
    }

    //报文
    public function data(Request $request)
    {
        $id = $request->input('id', 0);

        $find = LazadaOrderModel::find($id);
        if(!$find){
            return $this->error('小包不存在');
        }

        if($find->data){
            $data = json_decode($find->data, true);
            unset($data['s']);
            $data = json_encode($data);
        }else{
            $data = '';
        }


//        $log = LogModel::find($find->log_id);
//
//        $data = [];
//        if($log){
//            $data = json_decode($log->data, true);
//            unset($data['s']);
//            $data = json_encode($data);
//        }

        return $this->success($data);
    }

    public function get_node_list(Request $request)
    {
        $id = $request->input('id', 0);

        $find = LazadaOrderModel::find($id);
        if(!$find){
            return $this->error('小包不存在');
        }
        $record = NodeRecordModel::where('order_id', $id)->where('type', 2)->orderBy('id', 'desc')->get();

        $list = $record->map(function ($item) {
            return [
                'id' => $item->id,
                'node_name' => $item->node->name_cn,
                'status' => $item->status == 1 ? '成功' : '失败',
                'datetime' => $item->datetime,
                'created_at' => $item->created_at->toDateTimeString()
            ];
        });

        return $this->success($list);
    }


    //未更新小包
    public function unupdate_smallbag(Request $request)
    {
        $page = $request->input('page', 1);
        $limit = $request->input('limit', 20);
        $orderCode = $request->input('order_code', '');
        $trackingNumber = $request->input('trackingNumber', '');
        $des_country_id = $request->input('des_country_id', '');
        $node_id = $request->input('node_id', '');
        $goods_attr = $request->input('goods_attr', '');

        $query = \App\Models\lazada\OrderModel::query()->with(['customer', 'destination', 'system_node', 'platform_node']);

        if($orderCode){
            $query->where('order_code', $orderCode);
        }

        if($goods_attr){
            $query->where('goods_attr', $goods_attr);
        }

        if($des_country_id){
            $query->where('des_country_id', $des_country_id);
        }

        if($node_id){
            $query->where('system_node_id', $node_id);
        }

        $query->whereColumn('system_node_id', '<>', 'platform_node_id');

        $total = $query->count('id');
        $items = $query
            ->offset(($page-1) * $limit)
            ->limit($limit)
            ->orderBy('id', 'desc')
            ->get();

        $list = $items->map(function($item){
            $res = [
                'id' => $item->id,
                'customer_name' => $item->customer->name,
                'des_country_name' => $item->des_country_code,
                'goods_attr' => OrderModel::GOODS_ATTR_MAPS[$item->goods_attr] ?? '',
                'system_node' => $item->system_node->name_cn ?? '',
                'platform_node' => $item->platform_node->name_cn ?? '',

            ];
            return $res;
        });


        return $this->success(['list' => $list, 'total' => $total]);

    }

    /**更新本地系统节点
     * Notes:
     * User: xiangzi
     * Date: 2024/11/1
     * Time: 上午10:38
     * @return \Illuminate\Http\JsonResponse
     */
    public function update_system_node(Request $request)
    {
        $auth = $request->get('auth');
        $params = $request->all();

        $validator = Validator::make($params, [
            'id' => 'required|array',
            'node_id' => 'required',
            'datetime' => 'required'
        ], [
            'id.required' => 'id不能为空',
            'node_id.required' => '请选择节点',
            'datetime' => '请填写时间'
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }

        $ids = $params['id'];

        DB::beginTransaction();
        try{
            foreach ($ids as $id){
                $find = LazadaOrderModel::find($id);

                if(!$find){
                    return $this->error('小包不存在');
                }

                if($find->system_node_id != $find->platform_node_id){
                    return $this->error('小包【'.$find->orderCode.'】还未更新');
                }

                $find->system_node_id = $params['node_id'];
                $find->save();

                $record = new NodeRecordModel();
                $record->type = 1;
                $record->customer_id = $find->customer_id;
                $record->node_id = $params['node_id'];
                $record->order_id = $find->id;
                $record->trackingNumber = $find->trackingNumber;
                $record->orderCode = $find->orderCode;
                $record->datetime = $params['datetime'];
                $record->record_type = 2;
                $record->created_admin_id = $auth->id;
                $record->save();
            }

            DB::commit();

        }catch (AppException $e){
            DB::rollBack();
            return $this->error($e->getMessage());
        }

        return $this->success();
    }

    /**
     * Notes:更新平台节点
     * User: xiangzi
     * Date: 2024/11/1
     * Time: 上午10:39
     * @return \Illuminate\Http\JsonResponse
     */
    public function update_platform_node(Request $request)
    {
        $auth = $request->get('auth');
        $ids = $request->input('id',  []);

        $check = LazadaOrderModel::whereIn('id', $ids)->whereColumn('system_node_id', '<>', 'platform_node_id')->count();

        if($check != count($ids)){
            return $this->error('请选择未更新的数据');
        }

        DB::beginTransaction();
        try{
            foreach ($ids as $id){
                $find = LazadaOrderModel::find($id);

                if(!$find){
                    return $this->error('小包不存在');
                }

                $node = NodeModel::find($find['system_node_id']);

                $call_back = new CallBack();
                if($node->api == 'glcDeliveryLineHaulPickUpCallback'){
                    $res = $call_back->delivery_line_haul_pick_up_callback($id, $find->system_node_id, date('Y-m-d H:i:s'));
                }else if($node->api == 'glcDeliveryLineHaulPreBookingCallback'){
                    $res = $call_back->delivery_line_haul_pre_booking_callback($id, $find->system_node_id, date('Y-m-d H:i:s'));
                }else if($node->api == 'glcTransitLinehaulDepartureCallback'){
                    $res = $call_back->transit_line_haul_departure_callback($id, $find->system_node_id, date('Y-m-d H:i:s'));
                }else if($node->api == 'glcCustomsCcExStartCallback'){
                    $res =$call_back->customs_cc_ex_start_callback($id, $find->system_node_id, date('Y-m-d H:i:s'));
                } else if($node->api == 'glcCustomsCcExFailureCallback'){
                    $res = $call_back->customs_cc_ex_failure_callback($id, $find->system_node_id, date('Y-m-d H:i:s'));
                }else if($node->api == 'glcCustomsCcExSuccessCallback'){
                    $res = $call_back->customs_cc_ex_success_callback($id, $find->system_node_id, date('Y-m-d H:i:s'));
                }else if($node->api == 'glcLineHaulHoAirlineFailedCallback'){
                    $res = $call_back->line_haul_ho_airline_failed_callback($id, $find->system_node_id, date('Y-m-d H:i:s'));
                }else if($node->api == 'glcDeliveryLineHaulExceptionCallback'){
                    $res = $call_back->delivery_line_haul_exception_callback($id, $find->system_node_id, date('Y-m-d H:i:s'), '');
                }else if($node->api == 'glcDeliveryLineHaulHoAirlineCallback'){
                    $res = $call_back->delivery_line_haul_ho_airline_callback($id, $find->system_node_id, date('Y-m-d H:i:s'));
                }else if($node->api == 'glcDeliveryLineHaulDepartureCallback'){
                    $res = $call_back->delivery_line_haul_departure_callback($id, $find->system_node_id, date('Y-m-d H:i:s'));
                }else if($node->api == 'glcDeliveryLineHaulArrivalCallback'){
                    $res = $call_back->delivery_line_haul_arrival_callback($id, $find->system_node_id, date('Y-m-d H:i:s'));
                }else if($node->api == 'glcCustomsCcImStartCallback'){
                    $res = $call_back->customs_cc_im_start_callback($id, $find->system_node_id, date('Y-m-d H:i:s'));
                }else if($node->api == 'glcCustomsCcImAbnormalCallback'){
                    $res = $call_back->customs_cc_im_abnormal_callback($id, $find->system_node_id, date('Y-m-d H:i:s'));
                }else if($node->api == 'glcCustomsCcImSuccessCallback'){
                    $res = $call_back->customs_cc_im_success_callback($id, $find->system_node_id, date('Y-m-d H:i:s'));
                }else if($node->api == 'glcCustomsHoOutSuccessCallback'){
                    $res = $call_back->customs_ho_out_success_callback($id, $find->system_node_id, date('Y-m-d H:i:s'));
                }else{
                    return $this->error('接口不存在');
                }


                $record = new NodeRecordModel();
                $record->type = 2;
                $record->customer_id = $find->customer_id;
                $record->node_id = $find->system_node_id;
                $record->order_id = $find->id;
                $record->orderCode = $find->orderCode;
                $record->trackingNumber = $find->trackingNumber;
                $record->datetime = date('Y-m-d H:i:s');
                $record->record_type = 2;
                $record->created_admin_id = $auth->id;

                if(!$res['result']){
                    $record->status = 0;
                    $record->save();
                    DB::commit();
                    return $this->error($res['msg']);
                }

                $find->platform_node_id = $find->system_node_id;
                $find->save();
                $record->save();
            }

            DB::commit();

        }catch (AppException $e){
            DB::rollBack();
            return $this->error($e->getMessage());
        }

        return $this->success();
    }

    public function common_exception_callback(Request $request)
    {
        $auth = $request->get('auth');
        $params = $request->all();

        $validator = Validator::make($params, [
            'id' => 'required|array',
            'code' => 'required',
            'datetime' => 'required',
        ], [
            'id.required' => 'id不能为空',
            'code.required' => '请选择异常类型',
            'datetime.required' => '请填写时间',
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }

        $ids = $params['id'];

        DB::beginTransaction();
        try{
            foreach ($ids as $id){
                $find = LazadaOrderModel::find($id);

                if(!$find){
                    return $this->error('小包不存在');
                }

                $find->exception_status = 1;
                $find->exception_code = $params['code'];
                $find->save();

                $record = new NodeRecordModel();
                $record->type = 2;
                $record->customer_id = $find->customer_id;
                $record->order_id = $find->id;
                $record->orderCode = $find->orderCode;
                $record->trackingNumber = $find->trackingNumber;
                $record->datetime = $params['datetime'];
                $record->record_type = 2;
                $record->created_admin_id = $auth->id;
                $record->save();

                $call_back = new CallBack();

                $res = $call_back->delivery_line_haul_exception_callback($find->id, $params['code']);

                if(!$res['result']){
                    DB::rollBack();
                    return $this->error($res['msg']);
                }
            }

            DB::commit();

        }catch (AppException $e){
            DB::rollBack();
            return $this->error($e->getMessage());
        }

        return $this->success();
    }

    public function exception_code()
    {
        $list = ExceptionModel::select('code', 'desc')->get()->toArray();
        return $this->success($list);
    }


    public function export(Request $request) {
//        $order_code = $request->input('order_code', '');
//        $bigBagID = $request->input('bigBagID', '');
//        $take_order_sn = $request->input('take_order_sn', '');
//        $des_country_id = $request->input('des_country_id', '');
//        $customer_id = $request->input('customer_id', '');
//        $node_id = $request->input('node_id', '');
//        $warehouse_id = $request->input('warehouse_id', '');
//        $start_time = $request->input('startTime', '');
//        $end_time = $request->input('endTime', '');
//        $goods_attr = $request->input('goods_attr', '');

        $ids = $request->input('ids', []);

        if(!$ids){
            return $this->error('请选择要导出的数据');
        }

        $query = LazadaOrderModel::with(['customer', 'destination', 'take_order'])->whereIn('id', $ids);

        $items = $query
            ->orderBy('id', 'desc')
            ->get();

        $list = $items->map(function($item) {

            $res = [
                'customer_name' => $item->customer->name ?? '',
                'des_country_name' => $item->toLocation,
                'order_code' => $item->orderCode,
                'trackingNumber' => $item->trackingNumber,
                'bigBagID' => $item->bigBagID,
                'weight' => $item->weight,
                'goods_attr' => $item->cargoType == 1 ? '普货' : '敏货',
            ];
            return $res;
        });

        return Excel::download(new SmallBagExport(collect($list)), 'lazada小包数据.xlsx');
    }

}
